﻿@namespace BootstrapBlazor.Components
@typeparam TItem
@inherits BootstrapModuleComponentBase
@attribute [BootstrapModuleAutoLoader(JSObjectReference = true)]

<div @attributes="@AdditionalAttributes" class="@ClassName" style="@StyleString" id="@Id">
    <CascadingValue Value="this" IsFixed="true">
        @TableColumns?.Invoke(new TItem())
    </CascadingValue>
    @if (FirstRender)
    {
        if (ShowSkeleton)
        {
            <SkeletonTable ShowToolbar="@ShowToolbar"></SkeletonTable>
        }
        else if(ShowLoadingInFirstRender)
        {
            <div class="table-loading">
                <Spinner Color="Color.Primary" />
            </div>
        }
    }
    else
    {
        @if (ShowSearch && SearchMode == SearchMode.Top)
        {
            <div class="table-search">
                @RenderSearch
            </div>
        }

        @if (ShowToolbar)
        {
            <div class="table-toolbar">
                <TableToolbar GearIcon="@GearIcon" OnGetSelectedRows="@GetSelectedRows" IsAutoCollapsedToolbarButton="IsAutoCollapsedToolbarButton">
                    @if (TableToolbarBeforeTemplate != null)
                    {
                        @TableToolbarBeforeTemplate
                    }
                    @if (ShowDefaultButtons)
                    {
                        @if (ShowAddButton)
                        {
                            <TableToolbarButton TItem="TItem" Color="Color.Success" OnClick="AddAsync" Icon="@AddButtonIcon" Text="@AddButtonText" />
                        }
                        @if (!IsExcel && ShowEditButton)
                        {
                            <TableToolbarButton TItem="TItem" IsDisabled="GetEditButtonStatus()" Color="Color.Primary" OnClick="EditAsync" Icon="@EditButtonIcon" Text="@EditButtonText" IsEnableWhenSelectedOneRow="true" />
                        }
                        @if (ShowDeleteButton)
                        {
                            <TableToolbarPopConfirmButton TItem="TItem" Color="Color.Danger"
                                                          Icon="@DeleteButtonIcon" Text="@DeleteButtonText" IsDisabled="GetDeleteButtonStatus()"
                                                          OnBeforeClick="ConfirmDelete" OnConfirm="DeleteAsync"
                                                          CloseButtonText="@CancelDeleteButtonText" Content="@ConfirmDeleteContentText"
                                                          ConfirmButtonText="@ConfirmDeleteButtonText" ConfirmButtonColor="Color.Danger" />
                        }
                    }
                    @if (TableToolbarTemplate != null)
                    {
                        @TableToolbarTemplate
                    }
                </TableToolbar>
                <div class="float-end table-toolbar-button btn-group table-column-right">
                    @if (TableExtensionToolbarBeforeTemplate != null)
                    {
                        @TableExtensionToolbarBeforeTemplate
                    }
                    @if (ShowAdvancedSort)
                    {
                        <Button class="@AdvancedSortClass" Icon="@AdvancedSortButtonIcon" OnClickWithoutRender="ShowSortDialog">
                            <span class="d-none d-sm-inline-block">@AdvancedSortButtonText</span>
                        </Button>
                    }
                    @if (ShowRefresh)
                    {
                        <Button Icon="@RefreshButtonIcon" Color="@Color.Secondary" OnClickWithoutRender="@OnClickRefreshAsync">
                            <span class="d-none d-sm-inline-block">@RefreshButtonText</span>
                        </Button>
                    }
                    @if (!IsExcel && ShowCardView)
                    {
                        <Button Icon="@CardViewButtonIcon" Color="@Color.Secondary" OnClick="@OnClickCardView">
                            <span class="d-none d-sm-inline-block">@CardViewButtonText</span>
                        </Button>
                    }
                    @if (ShowColumnList)
                    {
                        <div class="dropdown-column btn-group dropdown">
                            <button class="btn btn-secondary dropdown-toggle" data-bs-auto-close="outside" data-bs-toggle="@ToggleDropdownString" type="button" title="@ColumnButtonTitleText">
                                <i class="@ColumnListButtonIcon"></i>
                                <span class="d-none d-sm-inline-block">@ColumnButtonText</span>
                                <span class="caret"></span>
                            </button>
                            <div class="dropdown-menu dropdown-menu-end shadow">
                                @foreach (var item in Columns)
                                {
                                    var poco = VisibleColumns.Find(i => i.Name == item.GetFieldName());
                                    if (poco == null)
                                    {
                                        poco = new(item.GetFieldName(), item.Visible);
                                        VisibleColumns.Add(poco);
                                    }
                                    <div class="dropdown-item">
                                        <Checkbox ShowAfterLabel="true" IsDisabled="@GetColumnsListState(item)"
                                        DisplayText="@item.GetDisplayName()" @bind-Value="@poco.Visible" OnValueChanged="visible => OnToggleColumnVisible(poco.Name, visible)">
                                        </Checkbox>
                                    </div>
                                }
                            </div>
                        </div>
                    }
                    @if (ShowExportButton)
                    {
                        <div class="dropdown-export btn-group dropdown">
                            <button class="btn btn-secondary dropdown-toggle" data-bs-toggle="@ToggleDropdownString" type="button" title="@ExportButtonText">
                                <i class="@ExportButtonIcon"></i>
                                <span class="d-none d-sm-inline-block">@ExportButtonText</span>
                                <span class="caret"></span>
                            </button>
                            <div class="dropdown-menu dropdown-menu-end shadow">
                                @if (ExportButtonDropdownTemplate != null)
                                {
                                    @ExportButtonDropdownTemplate(new TableExportContext<TItem>(this, Rows, BuildQueryPageOptions, ExportAsync))
                                }
                                else
                                {
                                    if (ShowExportCsvButton)
                                    {
                                        <div class="dropdown-item" @onclick="@ExportCsvAsync">
                                            <i class="@CsvExportIcon"></i>
                                            <span>@ExportCsvDropdownItemText</span>
                                        </div>
                                    }
                                    if (ShowExportExcelButton)
                                    {
                                        <div class="dropdown-item" @onclick="@ExportExcelAsync">
                                            <i class="@ExcelExportIcon"></i>
                                            <span>@ExportExcelDropdownItemText</span>
                                        </div>
                                    }
                                    if (ShowExportPdfButton)
                                    {
                                        <div class="dropdown-item" @onclick="@ExportPdfAsync">
                                            <i class="@PdfExportIcon"></i>
                                            <span>@ExportPdfDropdownItemText</span>
                                        </div>
                                    }
                                }
                            </div>
                        </div>
                    }
                    @TableExtensionToolbarTemplate
                </div>
                @if (ShowSearch && SearchMode == SearchMode.Popup)
                {
                    <div class="float-end table-toolbar-button btn-group">
                        @if (ShowSearchText)
                        {
                            <div class="input-group">
                                @if (ShowSearchTextTooltip)
                                {
                                    <Tooltip Placement="Placement.Top" Title="@SearchTooltip" Sanitize="false" IsHtml="true">
                                        <BootstrapInput class="table-toolbar-search" @onkeyup="OnSearchKeyUp" placeholder="@SearchPlaceholderText" @bind-Value="@SearchText" ShowLabel="false" />
                                    </Tooltip>
                                }
                                else
                                {
                                    <BootstrapInput class="table-toolbar-search" placeholder="@SearchPlaceholderText" @bind-Value="@SearchText" ShowLabel="false" />
                                }
                                <Button Color="@Color.Secondary" Icon="@SearchButtonIcon" OnClickWithoutRender="@SearchClick">
                                    <span class="d-none d-sm-inline-block">@SearchButtonText</span>
                                </Button>
                                @if (ShowResetButton)
                                {
                                    <Button Color="@Color.Secondary" Icon="@ResetSearchButtonIcon" OnClickWithoutRender="@ClearSearchClick">
                                        <span class="d-none d-sm-inline-block">@ResetSearchButtonText</span>
                                    </Button>
                                }
                                @if (ShowAdvancedSearch)
                                {
                                    @RenderAdvanceSearchButton
                                }
                            </div>
                        }
                        else if (ShowAdvancedSearch)
                        {
                            @RenderAdvanceSearchButton
                        }
                    </div>
                }
            </div>
        }

        @if (ShowTopPagination && IsPagination)
        {
            @RenderPagination
        }
        <div class="@WrapperClassName">
            @if (ActiveRenderMode == TableRenderMode.Table)
            {
                if (IsFixedHeader)
                {
                    <div class="table-fixed-header">
                        <table class="@TableClassName" style="@GetTableStyleString(true)" data-bb-name="@GetTableName(true)">
                            @RenderColGroup(true)
                            @RenderHeader(true)
                        </table>
                    </div>
                    <div class="table-fixed-body scroll">
                        @RenderTable(false)
                    </div>
                }
                else
                {
                    @RenderTable(true)
                }
            }
            else
            {
                foreach (var item in Rows)
                {
					OnBeforeRenderRow?.Invoke(item);
					<DynamicElement class="@GetRowClassString(item, "table-row")"
                                    TriggerContextMenu="ContextMenuZone != null" OnContextMenu="e => OnContextMenu(e, item)" @ontouchstart="e => OnTouchStart(e, item)" @ontouchend="OnTouchEnd"
                                    TriggerClick="@(ClickToSelect || OnClickRowCallback != null)" OnClick="() => ClickRow(item)">
                        @if (IsMultipleSelect)
                        {
                            <div class="table-cell">
                                <label>@CheckboxDisplayText</label>
                                @if (GetShowRowCheckbox(item))
                                {
                                    <Checkbox TValue="TItem" Value="@item" State="@RowCheckState(item)" OnStateChanged="OnCheck" @onclick:stopPropagation></Checkbox>
                                }
                            </div>
                        }
                        @if (ShowLineNo)
                        {
                            <div class="table-cell">
                                <label>@LineNoText</label>
                                <span>@(Rows.IndexOf(item) + 1 + (PageIndex -1) * PageItems)</span>
                            </div>
                        }
                        @if (ShowExtendButtons && IsExtendButtonsInRowHeader)
                        {
                            @RenderExtendButtons(item)
                        }
                        @foreach (var col in GetVisibleColumns())
                        {
                            var cellClass = "";
                            string? value = null;
                            <div class="table-cell">
                                <label>
                                    @col.GetDisplayName()
                                </label>
                                @if (col.OnCellRender != null)
                                {
                                    var cell = new TableCellArgs { Row = item, ColumnName = col.GetFieldName() };
                                    col.OnCellRender(cell);
                                    cellClass = cell.Class;
                                    value = cell.Value;
                                }
                                @if(value == null)
                                {
                                    <span>
                                        @GetValue(col, item)
                                    </span>
                                }
                                else
                                {
                                    <span class="@cellClass">
                                        @value
                                    </span>
                                }
                            </div>
                        }
                        @if (ShowExtendButtons && !IsExtendButtonsInRowHeader)
                        {
                            @RenderExtendButtons(item)
                        }
                    </DynamicElement>
                }
                @if (IsShowFooter)
                {
                    <div class="table-row table-footer">
                        <CascadingValue Value="true" Name="IsMobileMode" IsFixed="true">
                            <CascadingValue Value="@Rows" Name="TableFooterContext" IsFixed="true">
                                @TableFooter?.Invoke(Rows)
                            </CascadingValue>
                        </CascadingValue>
                    </div>
                }
            }
        </div>

        @if (!ShowTopPagination && IsPagination)
        {
            @RenderPagination
        }
        <div class="table-loader">
            <Spinner Color="Color.Primary" />
        </div>

        <Responsive OnBreakPointChanged="OnBreakPointChanged" />
    }
</div>

@code {
    RenderFragment<bool> RenderTable => hasHeader =>
    @<table class="@TableClassName" style="@GetTableStyleString(hasHeader)" data-bb-name="@GetTableName(hasHeader)">
        @RenderColGroup.Invoke(false)
        @if (hasHeader)
        {
            @RenderHeader(false)
        }
        <tbody>
            @if (InsertRowMode == InsertRowMode.First)
            {
                if (!IsExcel && EditMode == EditMode.EditForm && ShowAddForm)
                {
                    @RenderEditForm.Invoke((EditModel, ItemChangedType.Add))
                }
                if (AddInCell)
                {
                    @RenderRow(EditModel)
                }
            }
            @if (ScrollMode == ScrollMode.Virtual)
            {
                @if (Items != null)
                {
                    <Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize @ref="VirtualizeElement"
                        ItemSize="RowHeight" OverscanCount="10" Items="@Items.ToList()" ChildContent="RenderRow" />
                }
                else
                {
                    <Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize @ref="VirtualizeElement"
                        ItemSize="RowHeight" OverscanCount="10"
                        ItemsProvider="LoadItems" ItemContent="RenderRow">
                        <Placeholder>
                            @RenderPlaceHolderRow
                        </Placeholder>
                    </Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize>
                }
            }
            else
            {
                @foreach (var item in Rows)
                {
					OnBeforeRenderRow?.Invoke(item);
                    @RenderRow(item)
                    if (ShowDetails())
                    {
                        <tr class="@GetDetailRowClassString(item)">
                            <td>&nbsp;</td>
                            <td colspan="@GetColumnCount()">
                                <div class="table-cell is-wrap">
                                    @if (DetailRows.Contains(item))
                                    {
                                        @DetailRowTemplate!(item)
                                    }
                                    else
                                    {
                                        <div class="table-loading">
                                            <Spinner Color="Color.Primary" />
                                        </div>
                                    }
                                </div>
                            </td>
                        </tr>
                    }
                    if (!IsExcel && EditMode == EditMode.EditForm && ShowEditForm && SelectedRows.LastOrDefault() == item)
                    {
                        @RenderEditForm((EditModel, ItemChangedType.Update))
                    }
                }
                @if (IsShowEmpty)
                {
                    <tr>
                        <td colspan="@GetEmptyColumnCount()">
                            <Empty Text="@EmptyText" Image="@EmptyImage" Template="EmptyTemplate!">
                            </Empty>
                        </td>
                    </tr>
                }
            }
            @if (InsertRowMode == InsertRowMode.Last)
            {
                if (!IsExcel && EditMode == EditMode.EditForm && ShowAddForm)
                {
                    @RenderEditForm.Invoke((EditModel, ItemChangedType.Add))
                }
                if (AddInCell)
                {
                    @RenderRow(EditModel)
                }
            }
        </tbody>
        @if (IsShowFooter)
        {
            <tfoot class="@FooterClassString">
                <CascadingValue Value="false" Name="IsMobileMode" IsFixed="true">
                    <CascadingValue Value="@Rows" Name="TableFooterContext" IsFixed="true">
                        @if (FooterTemplate != null)
                        {
                            @FooterTemplate(Rows)
                        }
                        else
                        {
                            <tr>
                                @TableFooter?.Invoke(Rows)
                            </tr>
                        }
                    </CascadingValue>
                </CascadingValue>
            </tfoot>
        }
    </table>;

    RenderFragment<bool> RenderColGroup => hasScroll =>
    @<colgroup>
        @if (ShowDetails())
        {
            <col style="@GetColWidthString(DetailColumnWidth)" />
        }
        @if (IsMultipleSelect)
        {
            <col style="@GetColWidthString(MultiColumnWidth)" />
        }
        @if (ShowLineNo)
        {
            <col style="@GetColWidthString(LineNoColumnWidth)" />
        }
        @if (ShowExtendButtons && IsExtendButtonsInRowHeader)
        {
            <col style="@GetColWidthString(ExtendButtonColumnWidth)" />
        }
        @foreach (var col in GetVisibleColumns())
        {
            if (CheckShownWithBreakpoint(col))
            {
                <col style="@GetColWidthString(col.Width)" />
            }
        }
        @if (ShowExtendButtons && !IsExtendButtonsInRowHeader)
        {
            <col style="@GetColWidthString(ExtendButtonColumnWidth)" />
        }
        @if (hasScroll)
        {
            <col style="@ScrollWidthString" />
        }
    </colgroup>;

    RenderFragment<bool> RenderHeader => hasScroll =>
    @<thead class="@HeaderClass">
        @if (MultiHeaderTemplate != null)
        {
            @MultiHeaderTemplate
        }
        @if (GetShowHeader())
        {
            <tr>
                @if (ShowDetails())
                {
                    <th class="@DetailColumnClassString" style="@DetailColumnStyleString">
                        <div class="table-cell">&nbsp;</div>
                    </th>
                }
                @if (IsMultipleSelect)
                {
                    <th class="@MultiColumnClassString" style="@MultiColumnStyleString">
                        <div class="table-cell">
                            <Checkbox TValue="TItem" DisplayText="@CheckboxDisplayTextString" ShowLabel="false" ShowAfterLabel="@ShowCheckboxText"
                                      State="@HeaderCheckState()" OnStateChanged="OnHeaderCheck"></Checkbox>
                        </div>
                    </th>
                }
                @if (ShowLineNo)
                {
                    <th class="@LineNoColumnClassString" style="@LineNoColumnStyleString">
                        <div class="@LineCellClassString">@LineNoText</div>
                    </th>
                }
                @if (ShowExtendButtons && IsExtendButtonsInRowHeader)
                {
                    @RenderExtendButtonsHeader
                }
                @foreach (var col in GetVisibleColumns())
                {
                    @if (CheckShownWithBreakpoint(col))
                    {
                        var fieldName = col.GetFieldName();
                        var displayName = col.GetDisplayName();
                        <DynamicElement TagName="th" class="@GetHeaderClassString(col)" style="@GetFixedCellStyleString(col, 6)"
                                        TriggerClick="col.Sortable" OnClick="@OnClickHeader(col)" draggable="@DraggableString" @key="col">
                            <div class="@GetHeaderWrapperClassString(col)">
                                @if(col.ShowCopyColumn)
                                {
                                    if (ShowCopyColumnTooltip)
                                    {
                                        <Tooltip Placement="Placement.Top" Trigger="hover" Title="@CopyColumnTooltipText" data-bb-title="@CopyColumnCopiedTooltipText">
                                            <i class="@CopyColumnButtonIconString"></i>
                                        </Tooltip>
                                    }
                                    else
                                    {
                                        <i class="@CopyColumnButtonIconString"></i>
                                    }
                                }
                                @if(col.HeaderTemplate != null)
                                {
                                    @col.HeaderTemplate(col)
                                }
                                else if(col.ShowHeaderTooltip)
                                {
                                    <Tooltip class="@GetHeaderCellClassString(col)" style="@GetColWidthString(col.Width)" Title="@GetHeaderTooltipText(col.HeaderTextTooltip, displayName)" Trigger="hover">
                                        <span>@displayName</span>
                                    </Tooltip>
                                }
                                else if(col.Sortable)
                                {
                                    <Tooltip class="@GetHeaderCellClassString(col)" Title="@GetSortTooltip(col)" Trigger="hover">
                                        <span>@displayName</span>
                                    </Tooltip>
                                }
                                else
                                {
                                    <span class="@GetHeaderCellClassString(col)" style="@GetColWidthString(col.Width)">@displayName</span>
                                }
                                @if (col.Filterable && !ShowFilterHeader)
                                {
                                    <TableFilter Icon="@FilterIcon" Column="col" Table="this" IsActive="@Filters.ContainsKey(fieldName)" @onclick:stopPropagation />
                                }
                                @if (col.Sortable)
                                {
                                    <i class="@GetIconClassString(fieldName)"></i>
                                }
                            </div>
                            @if (!col.Fixed && AllowResizing)
                            {
                                <span class="col-resizer" data-bb-field="@col.GetFieldName()"></span>
                            }
                        </DynamicElement>
                    }
                }
                @if (ShowExtendButtons && !IsExtendButtonsInRowHeader)
                {
                    @RenderExtendButtonsHeader
                }
                @if (hasScroll)
                {
                    <th class="fixed-scroll"><div class="table-cell"><span>&nbsp;</span></div></th>
                }
            </tr>
        }
        @if (ShowFilterHeader)
        {
            <tr class="filter-header">
                @if (ShowDetails())
                {
                    <th>
                        <div class="table-cell">&nbsp;</div>
                    </th>
                }
                @if (IsMultipleSelect)
                {
                    <th>
                        <div class="table-cell">&nbsp;</div>
                    </th>
                }
                @if (ShowLineNo)
                {
                    <th>
                        <div class="table-cell">&nbsp;</div>
                    </th>
                }
                @if (ShowExtendButtons && IsExtendButtonsInRowHeader)
                {
                    <th class="@ExtendButtonsColumnClass" style="@GetFixedExtendButtonsColumnStyleString(CalcMargin(0))">
                        <div class="table-cell">&nbsp;</div>
                    </th>
                }
                @foreach (var col in GetVisibleColumns())
                {
                    if (CheckShownWithBreakpoint(col))
                    {
                        <th class="@GetHeaderClassString(col, true)" style="@GetFixedCellStyleString(col, 6)" @key="col">
                            <div class="table-cell">
                                @if(col.Filterable)
                                {
                                    <TableFilter Icon="@FilterIcon" Column="col" Table="this" IsHeaderRow="true" />
                                }
                            </div>
                        </th>
                    }
                }
                @if (ShowExtendButtons && !IsExtendButtonsInRowHeader)
                {
                    <th class="@ExtendButtonsColumnClass" style="@GetFixedExtendButtonsColumnStyleString(6)">
                        <div class="table-cell">&nbsp;</div>
                    </th>
                }
                @if (hasScroll)
                {
                    <th class="fixed-scroll"><div class="table-cell"><span>&nbsp;</span></div></th>
                }
            </tr>
        }
    </thead>;

    RenderFragment<TItem> RenderRow => item =>
    @<DynamicElement TagName="tr" class="@GetRowClassString(item)"
                     TriggerContextMenu="ContextMenuZone != null" OnContextMenu="e => OnContextMenu(e, item)" @ontouchstart="e => OnTouchStart(e, item)" @ontouchend="OnTouchEnd"
                     TriggerClick="@(ClickToSelect || OnClickRowCallback != null)" OnClick="() => ClickRow(item)"
                     TriggerDoubleClick="@(DoubleClickToEdit || OnDoubleClickRowCallback != null)" OnDoubleClick="() => DoubleClickRow(item)">
        @if (ShowDetails())
        {
            <td class="@DetailColumnClassString" style="@DetailColumnStyleString">
                <div class="@GetDetailBarClassString(item)">
                    @if (ShowDetailRow == null || ShowDetailRow.Invoke(item))
                    {
                        <i class="@GetDetailCaretClassString(item)" @onclick:stopPropagation @onclick="() => ExpandDetailRow(item)"></i>
                    }
                </div>
            </td>
        }
        @if (IsMultipleSelect)
        {
            <td class="@MultiColumnClassString" style="@MultiColumnStyleString">
                <div class="table-cell">
                @if (GetShowRowCheckbox(item))
                {
                    <Checkbox TValue="TItem" Value="@item" ShowLabel="false" State="RowCheckState(item)" OnStateChanged="OnCheck" @onclick:stopPropagation></Checkbox>
                }
                </div>
            </td>
        }
        @if (ShowLineNo)
        {
            <td class="@LineNoColumnClassString" style="@LineNoColumnStyleString">
                <div class="@LineCellClassString">@GetLineNo(item)</div>
            </td>
        }
        @{
            var index = 0;
            var colIndex = 0;
            var isInCell = EditInCell && SelectedRows.FirstOrDefault() == item;
        }
        @if (ShowExtendButtons && IsExtendButtonsInRowHeader)
        {
            @RenderRowExtendButtons(item)
        }
        @foreach (var col in GetVisibleColumns())
        {
            if (CheckShownWithBreakpoint(col))
            {
                if (colIndex > 1)
                {
                    colIndex--;
                    continue;
                }
                var cellClass = "";
                var colspan = 0;
                string? value = null;
                if (col.OnCellRender != null)
                {
                    var cell = new TableCellArgs { Row = item, ColumnName = col.GetFieldName() };
                    col.OnCellRender(cell);
                    cellClass = cell.Class;
                    colspan = cell.Colspan;
                    value = cell.Value;
                    colIndex = colspan;
                }
                <td colspan="@GetColspan(colspan)" class="@GetFixedCellClassString(col, cellClass)" style="@GetFixedCellStyleString(col)">
                    @{
                        var isFirstColOfTree = IsTree && index++ == 0;
                        var degree = 0;
                        var isExpend = false;
                        var hasChildren = false;
                        if (isFirstColOfTree)
                        {
                            var treeItem = TreeNodeCache.Find(TreeRows, item, out degree);
                            if(treeItem != null)
                            {
                                isExpend = treeItem.IsExpand;
                                hasChildren = treeItem.HasChildren;
                            }
                        }
                        var hesTreeChildren = isFirstColOfTree && hasChildren;
                    }
                    <DynamicElement TagName="div" TriggerClick="@hesTreeChildren"
                                    OnClick="@ToggleTreeRow(item)" StopPropagation="hesTreeChildren"
                                    class="@GetCellClassString(col, hesTreeChildren, isInCell)" style="@GetCellStyleString(col)">
                        @if (isFirstColOfTree)
                        {
                            <div class="is-node" style="@GetTreeStyleString(degree)">
                            @if (hesTreeChildren)
                            {
                                <i class="@GetTreeClassString(isExpend)"></i>
                            }
                            </div>
                        }
                        @if (IsExcel)
                        {
                            @RenderExcelCell(col, item, ItemChangedType.Update)
                        }
                        else if(isInCell)
                        {
                            @RenderCell(col, EditModel, ItemChangedType.Update)
                        }
                        else
                        {
                            var triggerDoubleClick = OnDoubleClickCellCallback != null;
                            <DynamicElement TagName="div" TriggerDoubleClick="triggerDoubleClick" GenerateElement="false"
                                            OnDoubleClick="TriggerDoubleClickCell(col, item)" StopPropagation="true"
                                            class="@GetDoubleClickCellClassString(triggerDoubleClick)">
                                @if (value == null)
                                {
                                    @GetValue(col, item)
                                }
                                else
                                {
                                    @value
                                }
                            </DynamicElement>
                        }
                    </DynamicElement>
                </td>
            }
        }
        @if (ShowExtendButtons && !IsExtendButtonsInRowHeader)
        {
            @RenderRowExtendButtons(item)
        }
    </DynamicElement>;

    RenderFragment RenderPlaceHolderRow =>
    @<tr>
        @if (IsMultipleSelect)
        {
            <td>
                <div class="table-cell">
                    <Checkbox TValue="TItem" ShowLabel="false" State="CheckboxState.UnChecked"></Checkbox>
                </div>
            </td>
        }
        @if (ShowLineNo)
        {
            <td><div class="table-cell is-ph"></div></td>
        }
        @if (ShowExtendButtons && IsExtendButtonsInRowHeader)
        {
            <td><div class="table-cell is-ph"></div></td>
        }
        @foreach (var col in GetVisibleColumns())
        {
            <td><div class="table-cell is-ph"></div></td>
        }
        @if (ShowExtendButtons && !IsExtendButtonsInRowHeader)
        {
            <td><div class="table-cell is-ph"></div></td>
        }
    </tr>;

    RenderFragment<(TItem Item, ItemChangedType ChangedType)> RenderEditForm => item =>
    @<tr class="is-editform">
        @{
            var colspanCount = GetColumnCount();
            if (IsMultipleSelect) colspanCount++;
            if (ShowLineNo) colspanCount++;
            if (ShowDetails()) colspanCount++;
            if (ShowExtendButtons) colspanCount++;
        }
        <td colspan="@colspanCount">
            <div class="table-cell">
                @if (EditTemplate != null)
                {
                    @EditTemplate.Invoke(item.Item)
                }
                else
                {
                    <ValidateForm Model="@item.Item" OnValidSubmit="context => SaveAsync(context, item.ChangedType)">
                        <EditorForm TModel="TItem" Items="Columns.Where(c => c.Editable)" ItemsPerRow="EditDialogItemsPerRow" RowType="EditDialogRowType" LabelAlign="EditDialogLabelAlign">
                            <Buttons>
                                <div class="text-end">
                                    @if(!IsTracking)
                                    {
                                        <Button Color="Color.Secondary" Icon="@CloseButtonIcon" Text="@CancelDeleteButtonText" OnClick="CancelSave"></Button>
                                    }
                                    <Button Color="Color.Primary" ButtonType="ButtonType.Submit" Icon="@SaveButtonIcon" Text="@SaveButtonText" class="ms-2"></Button>
                                </div>
                            </Buttons>
                        </EditorForm>
                    </ValidateForm>
                }
            </div>
        </td>
    </tr>;

    RenderFragment RenderAdvanceSearchButton =>
    @<Button class="@AdvanceSearchClass" Icon="@AdvanceButtonIcon" OnClickWithoutRender="ShowSearchDialog">
        <span class="d-none d-sm-inline-block">@AdvanceButtonText</span>
    </Button>;

    RenderFragment RenderExtendButtonsHeader =>
    @<th class="@ExtendButtonsColumnClass" style="@GetFixedExtendButtonsColumnStyleString(6)">
        <div class="@ExtendButtonsCellClassString">
            @ColumnButtonTemplateHeaderText
        </div>
    </th>;

    RenderFragment<TItem> RenderExtendButtons => item =>
    @<div class="table-cell">
        <label>@ColumnButtonTemplateHeaderText</label>
        <span class="btn-group">
            @if (BeforeRowButtonTemplate != null)
            {
                <TableExtensionButton OnClickButton="cell => OnClickExtensionButton(item, cell)">
                    @BeforeRowButtonTemplate.Invoke(item)
                </TableExtensionButton>
            }
            @if (GetShowExtendEditButton(item))
            {
                <Button Size="Size.ExtraSmall" OnClick="() => ClickEditButton(item)" Icon="@EditButtonIcon" Text="@EditButtonText"></Button>
            }
            @if (GetShowExtendDeleteButton(item))
            {
                <PopConfirmButton Placement="Placement.Left" Size="Size.ExtraSmall"
                                  Color="Color.Danger" Icon="@DeleteButtonIcon" Text="@DeleteButtonText"
                                  CloseButtonText="@CancelDeleteButtonText"
                                  Content="@ConfirmDeleteContentText"
                                  ConfirmButtonColor="Color.Danger"
                                  ConfirmButtonText="@ConfirmDeleteButtonText"
                                  OnBeforeClick="@ClickBeforeDelete(item)"
                                  OnConfirm="DeleteAsync" />
            }
            @if (RowButtonTemplate != null)
            {
                <TableExtensionButton OnClickButton="cell => OnClickExtensionButton(item, cell)">
                    @RowButtonTemplate.Invoke(item)
                </TableExtensionButton>
            }
        </span>
    </div>;

    RenderFragment<TItem> RenderRowExtendButtons => item =>
    @<td class="@FixedExtendButtonsColumnClassString" style="@GetFixedExtendButtonsColumnStyleString()">
        <div class="@ExtendButtonsCellClassString">
            <div class="btn-group" @onclick:stopPropagation="true">
                @{
                    var isInCell = EditInCell && SelectedRows.FirstOrDefault() == item;
                }
                @if (!isInCell)
                {
                    <TableExtensionButton OnClickButton="cell => OnClickExtensionButton(item, cell)">
                        @BeforeRowButtonTemplate?.Invoke(item)
                    </TableExtensionButton>
                }
                @if (!IsExcel && GetShowExtendEditButton(item))
                {
                    @if (isInCell)
                    {
                        <Button Size="Size.ExtraSmall" OnClick="ClickUpdateButtonCallback" Color="Color.Success" Icon="@SaveButtonIcon" Text="@SaveButtonText"></Button>
                        @if (!IsTracking)
                        {
                            <Button Size="Size.ExtraSmall" OnClick="@CancelSave" Color="Color.Warning" Icon="@CancelButtonIcon" Text="@CancelButtonText"></Button>
                        }
                    }
                    else
                    {
                        <Button Size="Size.ExtraSmall" OnClick="() => ClickEditButton(item)" Icon="@EditButtonIcon" Text="@EditButtonText"></Button>
                    }
                }
                @if (!isInCell && GetShowExtendDeleteButton(item))
                {
                    <PopConfirmButton Placement="Placement.Left" Size="Size.ExtraSmall"
                                      Color="Color.Danger" Icon="@DeleteButtonIcon" Text="@DeleteButtonText"
                                      CloseButtonText="@CancelDeleteButtonText" Content="@ConfirmDeleteContentText"
                                      ConfirmButtonColor="Color.Danger" ConfirmButtonText="@ConfirmDeleteButtonText"
                                      OnBeforeClick="@ClickBeforeDelete(item)"
                                      OnConfirm="DeleteAsync" />
                }
                @if (!isInCell)
                {
                    <TableExtensionButton OnClickButton="cell => OnClickExtensionButton(item, cell)">
                        @RowButtonTemplate?.Invoke(item)
                    </TableExtensionButton>
                }
            </div>
        </div>
    </td>;

    RenderFragment RenderSearch =>
    @<Card IsCollapsible="true" HeaderText="@SearchModalTitle" Collapsed="CollapsedTopSearch">
        <HeaderTemplate>
            @if (ShowSearchText)
            {
                <div class="input-group">
                    @if (ShowSearchTextTooltip)
                    {
                        <Tooltip Placement="Placement.Top" Title="@SearchTooltip" Sanitize="false" IsHtml="true">
                            <BootstrapInput class="table-toolbar-search" placeholder="@SearchPlaceholderText" @onkeyup="OnSearchKeyUp" @bind-Value="@SearchText">
                            </BootstrapInput>
                        </Tooltip>
                    }
                    else
                    {
                        <BootstrapInput class="table-toolbar-search" placeholder="@SearchPlaceholderText" @onkeyup="OnSearchKeyUp" @bind-Value="@SearchText" >
                        </BootstrapInput>
                    }
                    @if (ShowResetButton)
                    {
                        <Button Color="Color.Secondary" Icon="@ResetSearchButtonIcon" OnClickWithoutRender="ClearSearchClick">
                            <span class="d-none d-sm-inline-block">@ResetSearchButtonText</span>
                        </Button>
                    }
                    <Button Color="Color.Secondary" Icon="@SearchButtonIcon" OnClickWithoutRender="SearchClick">
                        <span class="d-none d-sm-inline-block">@SearchButtonText</span>
                    </Button>
                </div>
            }
            <div class="table-search-buttons">
                @if (ShowResetButton)
                {
                    <Button Color="Color.Secondary" Icon="@ResetSearchButtonIcon" class="btn-xs ms-2" OnClickWithoutRender="ClearSearchClick">
                        <span class="d-none d-sm-inline-block">@ResetSearchButtonText</span>
                    </Button>
                }
                @if (ShowSearchButton)
                {
                    <Button Color="Color.Primary" Icon="@SearchButtonIcon" class="btn-xs ms-2" OnClickWithoutRender="SearchClick">
                        <span class="d-none d-sm-inline-block">@SearchButtonText</span>
                    </Button>
                }
            </div>
        </HeaderTemplate>
        <BodyTemplate>
            @if(CustomerSearchModel != null && CustomerSearchTemplate != null)
            {
                @CustomerSearchTemplate(CustomerSearchModel)
            }
            else if(SearchTemplate != null)
            {
                @SearchTemplate(SearchModel)
            }
            else
            {
                <CascadingValue Value="true" IsFixed="true" Name="IsSearch">
                    <EditorForm Model="SearchModel" Items="GetSearchColumns()" ItemsPerRow="SearchDialogItemsPerRow" RowType="SearchDialogRowType" LabelAlign="SearchDialogLabelAlign">
                    </EditorForm>
                </CascadingValue>
            }
        </BodyTemplate>
    </Card>;

    RenderFragment RenderPageInfo =>
    @<div class="table-page-info">
        <div class="me-2">@PageInfoLabelString</div>
        <Select Items="@GetPageItemsSource()" Value="PageItems" OnValueChanged="@OnPageItemsValueChanged"></Select>
        @if (PageInfoBodyTemplate != null)
        {
            @PageInfoBodyTemplate
        }
    </div>;

    RenderFragment RenderPagination =>
    @<Pagination PageCount="@PageCount" PageIndex="@PageIndex" OnPageLinkClick="@OnPageLinkClick"
                 ShowGotoNavigator="ShowGotoNavigator" GotoTemplate="GotoTemplate!" GotoNavigatorLabelText="@GotoNavigatorLabelText"
                 ShowPageInfo="ShowPageInfo" PageInfoTemplate="InternalPageInfoTemplate" />;
}
